{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3-3,高阶API示范\n",
    "\n",
    "下面的范例使用TensorFlow的高阶API实现线性回归模型。\n",
    "\n",
    "TensorFlow的高阶API主要为tf.keras.models提供的模型的类接口。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用Keras接口有以下3种方式构建模型：使用Sequential按层顺序构建模型，使用函数式API构建任意结构模型，继承Model基类构建自定义模型。\n",
    "\n",
    "此处分别演示使用Sequential按层顺序构建模型以及继承Model基类构建自定义模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一，使用Sequential按层顺序构建模型【面向新手】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras import models,layers,optimizers\n",
    "\n",
    "#样本数量\n",
    "n = 800\n",
    "\n",
    "# 生成测试用数据集\n",
    "X = tf.random.uniform([n,2],minval=-10,maxval=10) \n",
    "w0 = tf.constant([[2.0],[-1.0]])\n",
    "b0 = tf.constant(3.0)\n",
    "\n",
    "Y = X@w0 + b0 + tf.random.normal([n,1],mean = 0.0,stddev= 2.0)  # @表示矩阵乘法,增加正态扰动"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                (None, 1)                 3         \n",
      "=================================================================\n",
      "Total params: 3\n",
      "Trainable params: 3\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "\n",
    "linear = models.Sequential()\n",
    "linear.add(layers.Dense(1, input_shape=(2,)))\n",
    "linear.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 800 samples\n",
      "Epoch 1/200\n",
      "800/800 [==============================] - 0s 256us/sample - loss: 120.5590 - mae: 9.3551\n",
      "Epoch 2/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 115.2476 - mae: 9.1433\n",
      "Epoch 3/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 110.2005 - mae: 8.9358\n",
      "Epoch 4/200\n",
      "800/800 [==============================] - 0s 39us/sample - loss: 105.3431 - mae: 8.7319\n",
      "Epoch 5/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 100.7100 - mae: 8.5346\n",
      "Epoch 6/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 96.2789 - mae: 8.3403\n",
      "Epoch 7/200\n",
      "800/800 [==============================] - 0s 39us/sample - loss: 92.0165 - mae: 8.1505\n",
      "Epoch 8/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 87.9862 - mae: 7.9630\n",
      "Epoch 9/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 84.0574 - mae: 7.7768\n",
      "Epoch 10/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 80.3335 - mae: 7.5966\n",
      "Epoch 11/200\n",
      "800/800 [==============================] - 0s 39us/sample - loss: 76.7426 - mae: 7.4199\n",
      "Epoch 12/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 73.2993 - mae: 7.2437\n",
      "Epoch 13/200\n",
      "800/800 [==============================] - 0s 41us/sample - loss: 69.9741 - mae: 7.0743\n",
      "Epoch 14/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 66.8175 - mae: 6.9055\n",
      "Epoch 15/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 63.7816 - mae: 6.7386\n",
      "Epoch 16/200\n",
      "800/800 [==============================] - 0s 41us/sample - loss: 60.8428 - mae: 6.5750\n",
      "Epoch 17/200\n",
      "800/800 [==============================] - 0s 44us/sample - loss: 58.0410 - mae: 6.4164\n",
      "Epoch 18/200\n",
      "800/800 [==============================] - 0s 45us/sample - loss: 55.3603 - mae: 6.2612\n",
      "Epoch 19/200\n",
      "800/800 [==============================] - 0s 39us/sample - loss: 52.7939 - mae: 6.1052\n",
      "Epoch 20/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 50.3011 - mae: 5.9531\n",
      "Epoch 21/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 47.9300 - mae: 5.8053\n",
      "Epoch 22/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 45.6536 - mae: 5.6581\n",
      "Epoch 23/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 43.4751 - mae: 5.5146\n",
      "Epoch 24/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 41.3905 - mae: 5.3728\n",
      "Epoch 25/200\n",
      "800/800 [==============================] - 0s 41us/sample - loss: 39.3884 - mae: 5.2328\n",
      "Epoch 26/200\n",
      "800/800 [==============================] - 0s 47us/sample - loss: 37.4679 - mae: 5.0984\n",
      "Epoch 27/200\n",
      "800/800 [==============================] - 0s 46us/sample - loss: 35.6492 - mae: 4.9628\n",
      "Epoch 28/200\n",
      "800/800 [==============================] - 0s 42us/sample - loss: 33.8749 - mae: 4.8290\n",
      "Epoch 29/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 32.2115 - mae: 4.7024\n",
      "Epoch 30/200\n",
      "800/800 [==============================] - 0s 42us/sample - loss: 30.6130 - mae: 4.5786\n",
      "Epoch 31/200\n",
      "800/800 [==============================] - 0s 42us/sample - loss: 29.0884 - mae: 4.4563\n",
      "Epoch 32/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 27.6309 - mae: 4.3367\n",
      "Epoch 33/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 26.2465 - mae: 4.2203\n",
      "Epoch 34/200\n",
      "800/800 [==============================] - 0s 41us/sample - loss: 24.9255 - mae: 4.1070\n",
      "Epoch 35/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 23.6739 - mae: 3.9956\n",
      "Epoch 36/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 22.4821 - mae: 3.8880\n",
      "Epoch 37/200\n",
      "800/800 [==============================] - 0s 41us/sample - loss: 21.3336 - mae: 3.7825\n",
      "Epoch 38/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 20.2634 - mae: 3.6816\n",
      "Epoch 39/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 19.2375 - mae: 3.5838\n",
      "Epoch 40/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 18.2746 - mae: 3.4892\n",
      "Epoch 41/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 17.3442 - mae: 3.3976\n",
      "Epoch 42/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 16.4842 - mae: 3.3088\n",
      "Epoch 43/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 15.6621 - mae: 3.2203\n",
      "Epoch 44/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 14.8911 - mae: 3.1368\n",
      "Epoch 45/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 14.1577 - mae: 3.0535\n",
      "Epoch 46/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 13.4720 - mae: 2.9759\n",
      "Epoch 47/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 12.8179 - mae: 2.8990\n",
      "Epoch 48/200\n",
      "800/800 [==============================] - 0s 40us/sample - loss: 12.2136 - mae: 2.8281\n",
      "Epoch 49/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 11.6375 - mae: 2.7584\n",
      "Epoch 50/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 11.0982 - mae: 2.6900\n",
      "Epoch 51/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 10.5966 - mae: 2.6261\n",
      "Epoch 52/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 10.1242 - mae: 2.5637\n",
      "Epoch 53/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 9.6780 - mae: 2.5063\n",
      "Epoch 54/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 9.2706 - mae: 2.4495\n",
      "Epoch 55/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 8.8804 - mae: 2.3957\n",
      "Epoch 56/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 8.5240 - mae: 2.3451\n",
      "Epoch 57/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 8.1835 - mae: 2.2972\n",
      "Epoch 58/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 7.8717 - mae: 2.2517\n",
      "Epoch 59/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 7.5824 - mae: 2.2081\n",
      "Epoch 60/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 7.3114 - mae: 2.1673\n",
      "Epoch 61/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 7.0637 - mae: 2.1280\n",
      "Epoch 62/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 6.8285 - mae: 2.0930\n",
      "Epoch 63/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 6.6147 - mae: 2.0595\n",
      "Epoch 64/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 6.4113 - mae: 2.0264\n",
      "Epoch 65/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 6.2281 - mae: 1.9961\n",
      "Epoch 66/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 6.0568 - mae: 1.9682\n",
      "Epoch 67/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 5.9005 - mae: 1.9410\n",
      "Epoch 68/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 5.7547 - mae: 1.9163\n",
      "Epoch 69/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 5.6173 - mae: 1.8923\n",
      "Epoch 70/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 5.4926 - mae: 1.8700\n",
      "Epoch 71/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 5.3783 - mae: 1.8489\n",
      "Epoch 72/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 5.2699 - mae: 1.8281\n",
      "Epoch 73/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 5.1725 - mae: 1.8103\n",
      "Epoch 74/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 5.0833 - mae: 1.7938\n",
      "Epoch 75/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.9956 - mae: 1.7780\n",
      "Epoch 76/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 4.9189 - mae: 1.7642\n",
      "Epoch 77/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 4.8462 - mae: 1.7510\n",
      "Epoch 78/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 4.7800 - mae: 1.7392\n",
      "Epoch 79/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.7182 - mae: 1.7277\n",
      "Epoch 80/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.6629 - mae: 1.7176\n",
      "Epoch 81/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.6062 - mae: 1.7079\n",
      "Epoch 82/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "800/800 [==============================] - 0s 36us/sample - loss: 4.5570 - mae: 1.6984\n",
      "Epoch 83/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.5099 - mae: 1.6897\n",
      "Epoch 84/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.4660 - mae: 1.6815\n",
      "Epoch 85/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.4259 - mae: 1.6741\n",
      "Epoch 86/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 4.3884 - mae: 1.6673\n",
      "Epoch 87/200\n",
      "800/800 [==============================] - 0s 29us/sample - loss: 4.3526 - mae: 1.6608\n",
      "Epoch 88/200\n",
      "800/800 [==============================] - 0s 32us/sample - loss: 4.3180 - mae: 1.6543\n",
      "Epoch 89/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 4.2885 - mae: 1.6484\n",
      "Epoch 90/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 4.2567 - mae: 1.6428\n",
      "Epoch 91/200\n",
      "800/800 [==============================] - 0s 46us/sample - loss: 4.2294 - mae: 1.6380\n",
      "Epoch 92/200\n",
      "800/800 [==============================] - 0s 45us/sample - loss: 4.2030 - mae: 1.6329\n",
      "Epoch 93/200\n",
      "800/800 [==============================] - 0s 39us/sample - loss: 4.1792 - mae: 1.6286\n",
      "Epoch 94/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.1539 - mae: 1.6239\n",
      "Epoch 95/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.1331 - mae: 1.6202\n",
      "Epoch 96/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.1110 - mae: 1.6155\n",
      "Epoch 97/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 4.0912 - mae: 1.6123\n",
      "Epoch 98/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.0729 - mae: 1.6087\n",
      "Epoch 99/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.0550 - mae: 1.6052\n",
      "Epoch 100/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.0372 - mae: 1.6017\n",
      "Epoch 101/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 4.0234 - mae: 1.5990\n",
      "Epoch 102/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 4.0066 - mae: 1.5957\n",
      "Epoch 103/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.9921 - mae: 1.5929\n",
      "Epoch 104/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.9795 - mae: 1.5901\n",
      "Epoch 105/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.9665 - mae: 1.5884\n",
      "Epoch 106/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.9548 - mae: 1.5861\n",
      "Epoch 107/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.9429 - mae: 1.5839\n",
      "Epoch 108/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.9300 - mae: 1.5815\n",
      "Epoch 109/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.9207 - mae: 1.5798\n",
      "Epoch 110/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.9115 - mae: 1.5784\n",
      "Epoch 111/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.9013 - mae: 1.5767\n",
      "Epoch 112/200\n",
      "800/800 [==============================] - 0s 29us/sample - loss: 3.8926 - mae: 1.5748\n",
      "Epoch 113/200\n",
      "800/800 [==============================] - 0s 30us/sample - loss: 3.8852 - mae: 1.5739\n",
      "Epoch 114/200\n",
      "800/800 [==============================] - 0s 30us/sample - loss: 3.8776 - mae: 1.5728\n",
      "Epoch 115/200\n",
      "800/800 [==============================] - 0s 32us/sample - loss: 3.8703 - mae: 1.5712\n",
      "Epoch 116/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.8629 - mae: 1.5699\n",
      "Epoch 117/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.8580 - mae: 1.5691\n",
      "Epoch 118/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.8519 - mae: 1.5683\n",
      "Epoch 119/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8463 - mae: 1.5673\n",
      "Epoch 120/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8421 - mae: 1.5667\n",
      "Epoch 121/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.8396 - mae: 1.5662\n",
      "Epoch 122/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.8340 - mae: 1.5654\n",
      "Epoch 123/200\n",
      "800/800 [==============================] - 0s 29us/sample - loss: 3.8287 - mae: 1.5641\n",
      "Epoch 124/200\n",
      "800/800 [==============================] - 0s 29us/sample - loss: 3.8234 - mae: 1.5636\n",
      "Epoch 125/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.8223 - mae: 1.5632\n",
      "Epoch 126/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 3.8173 - mae: 1.5624\n",
      "Epoch 127/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.8167 - mae: 1.5621\n",
      "Epoch 128/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.8109 - mae: 1.5614\n",
      "Epoch 129/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8093 - mae: 1.5618\n",
      "Epoch 130/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.8061 - mae: 1.5609\n",
      "Epoch 131/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8053 - mae: 1.5607\n",
      "Epoch 132/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.8028 - mae: 1.5605\n",
      "Epoch 133/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8004 - mae: 1.5602\n",
      "Epoch 134/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.8000 - mae: 1.5601\n",
      "Epoch 135/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7974 - mae: 1.5598\n",
      "Epoch 136/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7975 - mae: 1.5599\n",
      "Epoch 137/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 3.7945 - mae: 1.5594\n",
      "Epoch 138/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.7946 - mae: 1.5595\n",
      "Epoch 139/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7930 - mae: 1.5593\n",
      "Epoch 140/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7922 - mae: 1.5593\n",
      "Epoch 141/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7913 - mae: 1.5592\n",
      "Epoch 142/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7919 - mae: 1.5593\n",
      "Epoch 143/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7903 - mae: 1.5591\n",
      "Epoch 144/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7894 - mae: 1.5589\n",
      "Epoch 145/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7879 - mae: 1.5589\n",
      "Epoch 146/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7891 - mae: 1.5594\n",
      "Epoch 147/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7880 - mae: 1.5591\n",
      "Epoch 148/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7879 - mae: 1.5587\n",
      "Epoch 149/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7898 - mae: 1.5594\n",
      "Epoch 150/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7890 - mae: 1.5591\n",
      "Epoch 151/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.7871 - mae: 1.5590\n",
      "Epoch 152/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7875 - mae: 1.5589\n",
      "Epoch 153/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7855 - mae: 1.5584\n",
      "Epoch 154/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7851 - mae: 1.5586\n",
      "Epoch 155/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7857 - mae: 1.5585\n",
      "Epoch 156/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7854 - mae: 1.5587\n",
      "Epoch 157/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.7867 - mae: 1.5591\n",
      "Epoch 158/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7852 - mae: 1.5585\n",
      "Epoch 159/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7847 - mae: 1.5585\n",
      "Epoch 160/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7858 - mae: 1.5586\n",
      "Epoch 161/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7856 - mae: 1.5588\n",
      "Epoch 162/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7847 - mae: 1.5588\n",
      "Epoch 163/200\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7854 - mae: 1.5590\n",
      "Epoch 164/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7876 - mae: 1.5595\n",
      "Epoch 165/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7841 - mae: 1.5587\n",
      "Epoch 166/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7850 - mae: 1.5586\n",
      "Epoch 167/200\n",
      "800/800 [==============================] - 0s 38us/sample - loss: 3.7847 - mae: 1.5586\n",
      "Epoch 168/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7882 - mae: 1.5595\n",
      "Epoch 169/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7856 - mae: 1.5591\n",
      "Epoch 170/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7842 - mae: 1.5585\n",
      "Epoch 171/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7866 - mae: 1.5598\n",
      "Epoch 172/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7845 - mae: 1.5588\n",
      "Epoch 173/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7848 - mae: 1.5591\n",
      "Epoch 174/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7861 - mae: 1.5590\n",
      "Epoch 175/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7873 - mae: 1.5593\n",
      "Epoch 176/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7865 - mae: 1.5599\n",
      "Epoch 177/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7861 - mae: 1.5592\n",
      "Epoch 178/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7860 - mae: 1.5593\n",
      "Epoch 179/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7861 - mae: 1.5594\n",
      "Epoch 180/200\n",
      "800/800 [==============================] - 0s 30us/sample - loss: 3.7855 - mae: 1.5589\n",
      "Epoch 181/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7852 - mae: 1.5593\n",
      "Epoch 182/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 3.7869 - mae: 1.5596\n",
      "Epoch 183/200\n",
      "800/800 [==============================] - 0s 29us/sample - loss: 3.7857 - mae: 1.5591\n",
      "Epoch 184/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.7841 - mae: 1.5585\n",
      "Epoch 185/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.7881 - mae: 1.5594\n",
      "Epoch 186/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.7878 - mae: 1.5601\n",
      "Epoch 187/200\n",
      "800/800 [==============================] - 0s 31us/sample - loss: 3.7861 - mae: 1.5595\n",
      "Epoch 188/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7845 - mae: 1.5590\n",
      "Epoch 189/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 3.7850 - mae: 1.5588\n",
      "Epoch 190/200\n",
      "800/800 [==============================] - 0s 33us/sample - loss: 3.7841 - mae: 1.5588\n",
      "Epoch 191/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7857 - mae: 1.5593\n",
      "Epoch 192/200\n",
      "800/800 [==============================] - 0s 35us/sample - loss: 3.7856 - mae: 1.5598\n",
      "Epoch 193/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7851 - mae: 1.5587\n",
      "Epoch 194/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7858 - mae: 1.5594\n",
      "Epoch 195/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7879 - mae: 1.5597\n",
      "Epoch 196/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7850 - mae: 1.5592\n",
      "Epoch 197/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7845 - mae: 1.5590\n",
      "Epoch 198/200\n",
      "800/800 [==============================] - 0s 37us/sample - loss: 3.7869 - mae: 1.5593\n",
      "Epoch 199/200\n",
      "800/800 [==============================] - 0s 36us/sample - loss: 3.7875 - mae: 1.5596\n",
      "Epoch 200/200\n",
      "800/800 [==============================] - 0s 34us/sample - loss: 3.7839 - mae: 1.5586\n",
      "w = [[2.0084219]\n",
      " [-0.999575734]]\n",
      "b = [3.06585121]\n"
     ]
    }
   ],
   "source": [
    "### 使用fit方法进行训练\n",
    "\n",
    "linear.compile(optimizer=\"adam\", loss=\"mse\", metrics=['mae'])\n",
    "linear.fit(X, Y, batch_size=20, epochs=200)\n",
    "\n",
    "tf.print(\"w =\", linear.layers[0].kernel)\n",
    "tf.print(\"b =\", linear.layers[0].bias)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二，继承Model基类构建自定义模型【面向专家】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras import models,layers,optimizers,losses,metrics\n",
    "\n",
    "\n",
    "#打印时间分割线\n",
    "@tf.function\n",
    "def printbar():\n",
    "    ts = tf.timestamp()\n",
    "    today_ts = ts%(24*60*60)\n",
    "\n",
    "    hour = tf.cast(today_ts//3600+8,tf.int32)%tf.constant(24)\n",
    "    minite = tf.cast((today_ts%3600)//60,tf.int32)\n",
    "    second = tf.cast(tf.floor(today_ts%60),tf.int32)\n",
    "    \n",
    "    def timeformat(m):\n",
    "        if tf.strings.length(tf.strings.format(\"{}\",m))==1:\n",
    "            return(tf.strings.format(\"0{}\",m))\n",
    "        else:\n",
    "            return(tf.strings.format(\"{}\",m))\n",
    "    \n",
    "    timestring = tf.strings.join([timeformat(hour),timeformat(minite),\n",
    "                timeformat(second)],separator = \":\")\n",
    "    tf.print(\"==========\"*8,end = \"\")\n",
    "    tf.print(timestring)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#样本数量\n",
    "n = 800\n",
    "\n",
    "# 生成测试用数据集\n",
    "X = tf.random.uniform([n,2],minval=-10,maxval=10) \n",
    "w0 = tf.constant([[2.0],[-1.0]])\n",
    "b0 = tf.constant(3.0)\n",
    "\n",
    "Y = X@w0 + b0 + tf.random.normal([n,1],mean = 0.0,stddev= 2.0)  # @表示矩阵乘法,增加正态扰动\n",
    "\n",
    "ds_train = tf.data.Dataset.from_tensor_slices((X[0:n*3//4,:], Y[0:n*3//4,:])) \\\n",
    "            .shuffle(buffer_size=1000).batch(20) \\\n",
    "            .prefetch(tf.data.experimental.AUTOTUNE) \\\n",
    "            .cache()\n",
    "\n",
    "ds_valid = tf.data.Dataset.from_tensor_slices((X[n*3//4:,:],Y[n*3//4:,:])) \\\n",
    "             .shuffle(buffer_size = 1000).batch(20) \\\n",
    "             .prefetch(tf.data.experimental.AUTOTUNE) \\\n",
    "             .cache()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"mymodel\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                multiple                  3         \n",
      "=================================================================\n",
      "Total params: 3\n",
      "Trainable params: 3\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "\n",
    "class Mymodel(models.Model):\n",
    "    def __init__(self):\n",
    "        super(Mymodel, self).__init__()\n",
    "        \n",
    "    def build(self, input_shape):\n",
    "        self.dense1 = layers.Dense(1)\n",
    "        super(Mymodel, self).build(input_shape)\n",
    "        \n",
    "    def call(self, x):\n",
    "        y = self.dense1(x)\n",
    "        return (y)\n",
    "\n",
    "model = Mymodel()\n",
    "model.build(input_shape=(None, 2))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================================================================23:32:30\n",
      "Epoch=100,Loss:53.222084,MAE:5.51857185,Valid Loss:56.7886276,Valid MAE:5.72988653\n",
      "w= [[1.80102301]\n",
      " [-0.994384527]]\n",
      "b= [1.97587514]\n",
      "\n",
      "================================================================================23:32:36\n",
      "Epoch=200,Loss:28.9310379,MAE:3.6355021,Valid Loss:30.4502754,Valid MAE:3.66744852\n",
      "w= [[2.00816274]\n",
      " [-0.990700662]]\n",
      "b= [2.94288826]\n",
      "\n",
      "================================================================================23:32:42\n",
      "Epoch=300,Loss:20.7498302,MAE:2.97957468,Valid Loss:21.5465202,Valid MAE:2.95705509\n",
      "w= [[2.00814295]\n",
      " [-0.990829468]]\n",
      "b= [3.00022626]\n",
      "\n",
      "================================================================================23:32:48\n",
      "Epoch=400,Loss:16.6697521,MAE:2.65235257,Valid Loss:17.1050091,Valid MAE:2.60282373\n",
      "w= [[2.00815821]\n",
      " [-0.990836501]]\n",
      "b= [3.00035906]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "### 自定义训练循环(专家教程)\n",
    "\n",
    "optimizer = optimizers.Adam()\n",
    "loss_func = losses.MeanSquaredError()\n",
    "\n",
    "train_loss = tf.keras.metrics.Mean(name=\"train_loss\")\n",
    "train_metric = tf.keras.metrics.MeanAbsoluteError(name=\"train_mae\")\n",
    "\n",
    "valid_loss = tf.keras.metrics.Mean(name='valid_loss')\n",
    "valid_metric = tf.keras.metrics.MeanAbsoluteError(name='valid_mae')\n",
    "\n",
    "@tf.function\n",
    "def train_step(model, features, labels):\n",
    "    with tf.GradientTape() as tape:\n",
    "        predictions = model(features)\n",
    "        loss = loss_func(labels, predictions)\n",
    "    gradients = tape.gradient(loss, model.trainable_variables)\n",
    "    optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n",
    "    \n",
    "    train_loss.update_state(loss)\n",
    "    train_metric.update_state(labels, predictions)\n",
    "\n",
    "@tf.function\n",
    "def valid_step(model, features, labels):\n",
    "    predictions = model(features)\n",
    "    batch_loss = loss_func(labels, predictions)\n",
    "    valid_loss.update_state(batch_loss)\n",
    "    valid_metric.update_state(labels, predictions)\n",
    "\n",
    "@tf.function\n",
    "def train_model(model, ds_train, ds_valid, epochs):\n",
    "    for epoch in tf.range(1, epochs+1):\n",
    "        for features, labels in ds_train:\n",
    "            train_step(model, features, labels)\n",
    "        \n",
    "        for features, labels in ds_valid:\n",
    "            valid_step(model, features, labels)\n",
    "        \n",
    "        logs = 'Epoch={},Loss:{},MAE:{},Valid Loss:{},Valid MAE:{}'\n",
    "        \n",
    "        if epoch % 100 == 0:\n",
    "            printbar()\n",
    "            tf.print(tf.strings.format(logs, \n",
    "                    (epoch, train_loss.result(), train_metric.result(), \n",
    "                     valid_loss.result(), valid_metric.result())))\n",
    "            tf.print(\"w=\", model.layers[0].kernel)\n",
    "            tf.print(\"b=\", model.layers[0].bias)\n",
    "            tf.print(\"\")\n",
    "        \n",
    "        train_loss.reset_states()\n",
    "        train_metric.reset_states()\n",
    "        valid_loss.reset_states()\n",
    "        valid_metric.reset_states()\n",
    "        \n",
    "train_model(model, ds_train, ds_valid, 400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
